/**
 * 
 */
package com.app.service.item.itemspec;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.jboss.netty.util.internal.ConcurrentHashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.app.framework.exception.ResourceException;
import com.app.framework.orm.util.ClassHelper;
import com.app.framework.util.JSONUtil;
import com.app.framework.util.ReflectionUtil;
import com.app.framework.util.StringUtils;

/**
 * 设定道具管理类
 * @author lisong
 * @version 2013-3-29 下午4:58:05
 */
public class ItemSpecManager {

	/**
	 * key ItemSpec id
	 * value Item
	 */
	private static Map<String,ItemFace> items = new ConcurrentHashMap<String, ItemFace>();
	/**
	 * key ItemSpec.class.getName
	 * value itemSpec id
	 */
	private static Map<String,List<String>> itemGroup = new ConcurrentHashMap<String,List<String>>();
	
	private static ItemSpecManager instance = new ItemSpecManager();
	
	private ItemSpecManager() {
		load();
	}

	public static ItemSpecManager getInstance() {
		return instance;
	}
	
	/**
	 * 加载设定道具xml
	 */
	@SuppressWarnings("unchecked")
	private void load() throws ResourceException {
		int line = 1;
		String fileName = null;
		try {
			File dir = new File(System.getProperty("user.dir")+"/resource/item/");
			File[] files = dir.listFiles(new FileFilter() {
				@Override
				public boolean accept(File name) {
					if(name.isFile() && !name.isHidden()) {
						return true;
					}
					return false;
				}
			});
			for(File xml : files) {
				fileName = xml.getName();
				InputStream in = new FileInputStream(xml);
				DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
				DocumentBuilder builder=factory.newDocumentBuilder();
				Document document=builder.parse(in);
				Element rootElement=document.getDocumentElement();
				String classname = rootElement.getAttribute("class");
				Class<? extends ItemFace> clz = (Class<? extends ItemFace>) Class.forName(classname);
				NodeList elementList=rootElement.getChildNodes();
				List<String> itemIds = new ArrayList<String>();
				
				for(int i=0;i<elementList.getLength();i++) {
					line ++;
					Node curNode=elementList.item(i);
					if(curNode.getNodeType() == Node.ELEMENT_NODE) {
						NamedNodeMap nodeMap=curNode.getAttributes();
						ItemFace item = clz.newInstance();
						for(Field field : ReflectionUtil.getClassUnStaticUnFinalFields(clz).values()) {
							field.setAccessible(true);
							Node node = nodeMap.getNamedItem(field.getName());
							String json = node.getNodeValue();
							if(node != null && !StringUtils.isNullOrEmpty(json)) {
								if(JSONUtil.mayBeJSON(json)) {
									field.set(item, JSONUtil.toObject(json, field.getType()));
								}
								else {
									field.set(item, ClassHelper.getSimpleClassValue(json, field.getType()));
								}
							}
						}
						
						if(StringUtils.isNullOrEmpty(item.getId())) {
							throw new ResourceException("道具id为空 xml:"+fileName + ", line:"+line);
						}
						if(items.containsKey(item.getId())) {
							throw new ResourceException("该道具id已存在 id:"+item.getId()+", xml:"+fileName + ", line:"+line);
						}
						items.put(item.getId(), item);
						itemIds.add(item.getId());
					}
				}
				if(itemGroup.get(clz.getName()) == null) {
					itemGroup.put(clz.getName(), new ArrayList<String>());
				}
				itemGroup.put(clz.getName(), itemIds);
			}
		}catch (Exception e) {
			throw new ResourceException("载入设定数据失败: xml:"+fileName+", line:"+line,e);
		}
	}
	/**
	 * 获取道具
	 * @param id
	 * @return
	 */
	public ItemFace getItem(String id) {
		
		return items.get(id);
	}
	/**
	 * 获取指定道具类别的道具id集合
	 * @param clz
	 * @return
	 */
	public List<String> getItemSpecIds(Class<? extends ItemFace> itemType) {
		
		return itemGroup.get(itemType.getName());
	}
	/**
	 * 获取指定道具类别的道具实体集合
	 * @param clz
	 * @return 不会为null
	 */
	public List<ItemFace> getItemSpec(Class<? extends ItemFace> itemType) {
		List<ItemFace> ret = new ArrayList<ItemFace>();
		for(String id : itemGroup.get(itemType.getName())) {
			ret.add(getItem(id));
		}
		return ret;
	}
	/**
	 * 判断某一道具id是否属于指定的道具类别
	 * @param typeClz指定的道具类别
	 * @param id 道具id
	 * @return
	 */
	public boolean isItemType(Class<? extends ItemFace> itemType,String id) {
		if(itemGroup.get(itemType.getName()).contains(id)) {
			return true;
		}
		return false;
	}
	
	public void reload() {
		clear();
		load();
	}
	
	public void clear() {
		items.clear();
		itemGroup.clear();
	}
	public static void main(String[] args) {
		System.out.println(ItemSpecManager.getInstance().getItem(""));
	}
}
